package br.com.viewcar.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import br.com.viewcar.entity.HistoricoTransmissao;
import br.com.viewcar.entity.Veiculo;
import br.com.viewcar.entity.dto.PontoDTO;
import br.com.viewcar.util.CheckrotaUtil;
import br.com.viewcar.util.DateUtil;

@Repository
@Transactional
public class VeiculoService extends BaseService<Integer, Veiculo> {

	private static final Log logger = LogFactory.getLog(VeiculoService.class);

	@Autowired
	private UsuarioService usuarioService;


	@Autowired
	private HistoricoTransmissaoService historicoTransmissaoService;


	public List<Veiculo> findByPlaca(String placa){
		List<Veiculo> v = executeResultListQuery("findByCliente", placa);
		return v;
	}

	public List<Veiculo> findByVeiculoLista(Integer clienteId, Integer tipoVeiculoId, Integer marcaId, Integer modeloId){
		return executeResultListQuery("findByVeiculoLista", clienteId, tipoVeiculoId, marcaId, modeloId);
	}

	public List<Veiculo> findByCliente(Integer clienteId){
		return executeResultListQuery("findByCliente", clienteId);
	}

	public List<Veiculo> findByClienteTransmissao(Integer clienteId){
		return executeResultListQuery("findByClienteTransmissao", clienteId);
	}


	@Override
	@Transactional(readOnly = true)
	public List<Veiculo> retrieveAll() {

		if(CheckrotaUtil.isAdministradorSistema()) {
			return super.retrieveAll();
		}
		return super.retrieveAll();
		//return null;
	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Veiculo> retrieveByIds(List<Integer> veiculoIds) {

		if (veiculoIds != null && veiculoIds.size() > 0) {
			String idsList = veiculoIds.toString().replaceAll("\\[", "(").replaceAll("\\]", ")");
			Query query = entityManager.createQuery("SELECT v FROM Veiculo v WHERE v.id IN " + idsList);
			return query.getResultList();
		} else {
			return new ArrayList<Veiculo>();
		}
	}

	@Transactional(readOnly = true)
	public List<PontoDTO> searchPontosMonitoramento(List<Veiculo> veiculos, boolean exibirPontos, boolean exibirMensagens, boolean exibirRota, Float velocidadeMaxima, Date iniDay) {

		Map<Integer, List<HistoricoTransmissao>> mapTransmissoes = null;
		List<Integer> veiculoIds = new ArrayList<Integer>();

		for (Veiculo veiculo : veiculos) {
			veiculoIds.add(veiculo.getId());
		}

		if (exibirPontos) {
			Date endDay = DateUtil.getDateEndDay();
			mapTransmissoes  = historicoTransmissaoService.findByVeiculoList(veiculoIds, iniDay, endDay);
		}

		int k = 0;
		List<PontoDTO> pontos = new ArrayList<PontoDTO>();
		String s = "";

		try {
			for (Veiculo veiculo : veiculos) {

				if (veiculo.getDataTransmissao() != null) {

					PontoDTO m = new PontoDTO();
					try {
						m.setId(veiculo.getId());
						m.setNome(veiculo.getNome().replace("|", ":"));
						m.setPlaca(veiculo.getPlaca());
						m.setIgnicao(veiculo.getStatusIgnicao());
						m.setPanico(veiculo.getStatusPanico());
						m.setVelocidade(veiculo.getVelocidade());

						Float temperaturaAtual = veiculo.getTemperatura() == null || veiculo.getTemperatura() == -40 ? 0f: veiculo.getTemperatura();
						m.setTemperatura(temperaturaAtual);
						m.setOdometro(veiculo.getOdometro());

						Float kmAtual = veiculo.getOdometro() == null ? 0f: veiculo.getOdometro();
						m.setKmAtual(kmAtual);
						m.setDataTransmissao(veiculo.getDataTransmissao());

						String pontoNome = veiculo.getPonto() == null ? "" : veiculo.getPonto().getNome();
						m.setPontoMaisProximo(pontoNome);
						m.setDistPontoMaisProximo(veiculo.getDistancia());
						m.setCodigoExterno(veiculo.getCodigoExterno());
						m.setCor(veiculo.getCor());
						m.setAno(veiculo.getAno());

					} catch (Exception e) {
						logger.error(e.getMessage(), e);
					}

					if (veiculo.getGeometry() != null) {
						m.setLat((float) veiculo.getGeometry().getX());
						m.setLng((float) veiculo.getGeometry().getY());
					}

					m.setIndex(k++);
					pontos.add(m);
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return pontos;//classificar(pontos);
	}

	@SuppressWarnings("unused")
	@Transactional(readOnly = true)
	private List<PontoDTO> classificar(List<PontoDTO> list) {

		Collections.sort(list, new Comparator<PontoDTO>() {
			public int compare(PontoDTO m1, PontoDTO m2) {
				return m1.getDataTransmissao().before(m2.getDataTransmissao()) ? 1 : -1;
			}
		});
		return list;
	}

	public Boolean verificarSerial(Integer serialId, Integer veiculoId){

		List<Veiculo> list = new ArrayList<Veiculo>();
		if(veiculoId != null){
			list = executeResultListQuery("findBySerial", serialId, veiculoId);
		} else {
			list = executeResultListQuery("findBySerialVeicNull", serialId);
		}

		if( list == null || list.size() == 0){
			return false;
		} else {
			return true;
		}
	}
}